{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**问题：**\n",
    "假设你正在为一个电影推荐系统设计一个简单的KNN算法。我们有以下一些用户的电影评分数据，数据由两个特征组成：用户对电影A和电影B的评分，分别在1-5之间。用户的标签（电影类型偏好）是动作片（标签0）或者是喜剧片（标签1）。我们有一个新用户，他给电影A评分为3，电影B评分为4。请问这个用户可能偏好哪种类型的电影？\n",
    "\n",
    "**数据：**\n",
    "\n",
    "| 用户   | 电影A评分 | 电影B评分 | 偏好类型 |\n",
    "| ------ | --------- | --------- | -------- |\n",
    "| 用户1  | 5         | 1         | 动作片   |\n",
    "| 用户2  | 4         | 2         | 动作片   |\n",
    "| 用户3  | 2         | 5         | 喜剧片   |\n",
    "| 用户4  | 1         | 4         | 喜剧片   |\n",
    "| 用户5  | 3         | 2         | 动作片   |\n",
    "| 用户6  | 2         | 5         | 喜剧片   |\n",
    "\n",
    "你需要做以下步骤：\n",
    "1. 构造数据\n",
    "2. 创建KNN模型\n",
    "3. 使用数据训练模型\n",
    "4. 预测新用户的喜好"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 0. 引入核心包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.neighbors import KNeighborsClassifier"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "X = np.array([[1, 2], [2, 3], [3, 1], [6, 7], [7, 8], [8, 6]])\n",
    "\n",
    "y =  np.array([0, 0, 0, 1, 1, 1])# 0表示动作片，1表示喜剧片"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 创建 KNN 模型\n",
    "k = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "k=1\n",
    "knn = KNeighborsClassifier(n_neighbors=k)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-2 {color: black;}#sk-container-id-2 pre{padding: 0;}#sk-container-id-2 div.sk-toggleable {background-color: white;}#sk-container-id-2 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-2 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-2 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-2 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-2 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-2 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-2 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-2 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-2 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-2 div.sk-item {position: relative;z-index: 1;}#sk-container-id-2 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-2 div.sk-item::before, #sk-container-id-2 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-2 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-2 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-2 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-2 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-2 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-2 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-2 div.sk-label-container {text-align: center;}#sk-container-id-2 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-2 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier(n_neighbors=1)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">KNeighborsClassifier</label><div class=\"sk-toggleable__content\"><pre>KNeighborsClassifier(n_neighbors=1)</pre></div></div></div></div></div>"
      ],
      "text/plain": [
       "KNeighborsClassifier(n_neighbors=1)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn.fit(X, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 用模型推理(预测)用户的喜好"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "new_user = np.array([[3, 4]])\n",
    "prediction = knn.predict(new_user)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. 数据可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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IiIiqgitA07R3YqJiIiInlVaB5x58+bpow4iIiIindH6HBwiIiKiZ51GR3Bq166NK1euwNnZGY6OjmXe++bRo0c6K46IiIioIjQKOCtWrIC9vb3qv3lzPyIiInqWaRRwQkJCVP89YsQIne18/vz5WLBggVqbl5cX/vrrL53tg4iIiEyP1icZm5ub4+7du3BxcVFrf/jwIVxcXKBQKLQar3nz5ti3b9//CrKo8PM/iYiIiABUIOAIIUpsz8vLg5WVlfYFWFigbt26Wr+PiIiIqDQaB5xVq1YBACRJwrp162BnZ6faplAocOjQIXh7e2tdwNWrV+Hm5gZra2t06tQJixcvRv369Uvsm5eXh7y8PNXrzMxMAIBcLodcLtd632UpGk/X41YXpj5/gGvA+Zv2/AGuganPH9DfGlTFmkqitEMy/9KgQQMAQHJyMurVqwdzc3PVNisrK3h6emLhwoXo0KGDxjuPjY1FVlYWvLy8cPfuXSxYsACpqalITExUndT8tJLO2QGAqKgo2NraarxfIiIiMpzs7GwMGzYMGRkZcHBw0Ms+NA44Rbp164Zt27bB0dFR58X8888/8PDwwPLlyzF69Ohi20s6guPu7o60tDSdL5BcLsfevXsREBBQ7HEUpsDU5w9wDTh/054/wDUw9fkD+luDzMxMODs76zXgaH0OzoEDB/RRBwCgVq1aaNKkCa5du1bidplMBplMVqzd0tJSbx8+fY5dHZj6/AGuAedv2vMHuAamPn9A92tQFetZoUuWbt++jR07duDWrVvIz89X27Z8+fIKF5OVlYXr16/jzTffrPAYRERERFoHnP3796N///544YUX8Ndff6FFixZISkqCEAJ+fn5ajfX++++jX79+8PDwwJ07dzBv3jyYm5tj6NCh2pZFREREpKL1s6hmzZqF999/H+fPn4e1tTW2bt2KlJQUdOnSBYMGDdJqrNu3b2Po0KHw8vLC4MGD4eTkhOPHj6NOnTralkVERESkovURnEuXLmHTpk2Fb7awQE5ODuzs7LBw4UIEBQVh/PjxGo8VHR2t7e6JiIiIyqX1EZwaNWqozrtxdXXF9evXVdvS0tJ0VxkRERFRBWl9BKdjx444fPgwmjZtir59+2LatGk4f/48tm3bho4dO+qjRiIiIiKtaB1wli9fjqysLADAggULkJWVhR9//BGNGzeu1BVU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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.title(\"User Movie Preference\", size=15) \n",
    "plt.xlabel(\"Movie A rating\")\n",
    "plt.ylabel(\"Movie B rating\")\n",
    "plt.grid()\n",
    "\n",
    "# 绘制原始样本点，要求不同的影片喜好类别用不同的颜色标记\n",
    "# 提示: 用scatter散点图绘制，用它的参数c实现不同的类别用不同的颜色标记\n",
    "plt.scatter(X[:,0], X[:,1], c=y)\n",
    "\n",
    "# 绘制新数据点，用红色x标记，大小为8\n",
    "# 提示：用plt.plot()绘制，用它的参数marker实现不同的标记符号\n",
    "plt.plot(new_user[0,0], new_user[0,1], 'rx', markersize=8)\n",
    "\n",
    "# 新数据最近邻索引为第一个最近邻的索引\n",
    "dist, idx = knn.kneighbors(new_user)\n",
    "nearest = X[idx]# 获取最近邻点的坐标，这是一个列表，第一个元素是x坐标，第二个元素是y坐标\n",
    "\n",
    "# 用红线标记新数据点与最近邻点的连接线\n",
    "# 提示：用plt.plot()绘制，用 r-- 实现红色虚线\n",
    "plt.plot([new_user[0,0], nearest[0][0][0]], [new_user[0,1], nearest[0][0][1]], 'r--')\n",
    "\n",
    "# 为每个点添加坐标文本  \n",
    "for x, y in zip(X[:, 0], X[:, 1]):\n",
    "    plt.text(x, y+0.1, f'({x}, {y})') \n",
    "\n",
    "# 为新数据点添加坐标文本\n",
    "plt.text(new_user[0,0], new_user[0,1]+0.1, f'({new_user[0,0]}, {new_user[0,1]})')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
